﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.Files
{
    /// <summary>
    /// 文件魔数扩展类
    /// </summary>
    public static class FileMagicNumberExt
    {
        /// <summary>
        /// 文件扩展名
        /// </summary>
        private readonly static Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
        {
            { ".jpg", new List<byte[]> { new byte[] { 0xFF, 0xD8, 0xFF } } },
            { ".jpeg", new List<byte[]> { new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 } } },
            { ".png", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47 } } },
            { ".bmp", new List<byte[]> { new byte[] { 0x42, 0x4D } } },
            { ".gif", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } },

            { ".xls", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0 } } },
            { ".xlsx", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
            { ".doc", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0 } } },
            { ".docx", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x31, 0x57, 0x52, 0x64 } } },
            { ".ppt", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0 } } },
            { ".pptx", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },

            //{ ".wps", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0 } } },


            { ".mp4", new List<byte[]> { new byte[] { 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70 } } },
            { ".avi", new List<byte[]> { new byte[] { 0x52, 0x49, 0x46, 0x46 } } },
            { ".mov", new List<byte[]> { new byte[] { 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70 } } },
            { ".flw", new List<byte[]> { new byte[] { 0x46, 0x4C, 0x56, 0x01 } } },
            { ".ogg", new List<byte[]> { new byte[] { 0x4F, 0x67, 0x67, 0x53 } } },

            //pdf 魔数（%PDF-）+ 文件尾（%%EOF）
            { ".pdf", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46, 0x2D } } },
        };

        /// <summary>
        /// 验证表单文件是否是系统可上传的文件类型
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static bool IsValidToFileType(this IFormFile file, FileType fileTypeGroup)
        {
            var fileSignatures = GetFileSignatureByFileTypeGroup(fileTypeGroup);
            if (fileSignatures == null || fileSignatures.Count == 0)
            {
                return false;
            }
            // 检查扩展名
            var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
            if (string.IsNullOrEmpty(ext) || !fileSignatures.ContainsKey(ext))
                return false;

            bool isValid = false;
            // 检查文件签名
            using (var reader = new BinaryReader(file.OpenReadStream()))
            {
                var signatures = fileSignatures[ext];
                var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));

                isValid = signatures.Any(signature =>
                    headerBytes.Take(signature.Length).SequenceEqual(signature));
            }
            return isValid;
        }


        public static Dictionary<string, List<byte[]>> GetFileSignatureByFileTypeGroup(FileType fileTypeGroup)
        {
            var signatures = new Dictionary<string, List<byte[]>>();
            switch (fileTypeGroup)
            {
                case FileType.Image:
                    signatures.Add(".jpeg", _fileSignature[".jpeg"]);
                    signatures.Add(".jpg", _fileSignature[".jpg"]);
                    signatures.Add(".png", _fileSignature[".png"]);
                    signatures.Add(".bmp", _fileSignature[".bmp"]);
                    signatures.Add(".gif", _fileSignature[".gif"]);
                    break;
                case FileType.Video:
                    signatures.Add(".mp4", _fileSignature[".mp4"]);
                    signatures.Add(".avi", _fileSignature[".avi"]);
                    signatures.Add(".mov", _fileSignature[".mov"]);
                    signatures.Add(".flw", _fileSignature[".flw"]);
                    signatures.Add(".ogg", _fileSignature[".ogg"]);
                    break;
                case FileType.Excel:
                    signatures.Add(".xls", _fileSignature[".xls"]);
                    signatures.Add(".xlsx", _fileSignature[".xlsx"]);
                    break;
                case FileType.Word:
                    signatures.Add(".doc", _fileSignature[".doc"]);
                    signatures.Add(".docx", _fileSignature[".docx"]);
                    break;
                case FileType.Ppt:
                    signatures.Add(".doc", _fileSignature[".doc"]);
                    signatures.Add(".docx", _fileSignature[".docx"]);
                    break;
                case FileType.Pdf:
                    signatures.Add(".pdf", _fileSignature[".pdf"]);
                    break;
                case FileType.All:
                    signatures = _fileSignature;
                    break;
            }
            return signatures;
        }
    }


    /// <summary>
    /// 文件类型 
    /// </summary>
    public enum FileType
    {
        All = 255,
        Image = 1,
        Video = 2,
        Excel = 4,
        Word = 8,
        Ppt = 16,
        Pdf = 32,
        //Wps = 8,
    }

}
